﻿using System;
using System.Runtime.Serialization;

namespace Simp.CodeModel.Exceptions
{
	/// <summary>Thrown when a parameter is explicitely bound in a function call but doesn't exist.</summary>
	[Serializable()]
	public class ParameterBindingException : FunctionExceptionBase
	{
		private const string PARAMETER_NAME = "ParmaeterName";

		private readonly string _parameterName;

		/// <summary>Constructor taking the function and parameter names.</summary>
		/// <param name="functionName"/>
		/// <param name="parameterName"/>
		public ParameterBindingException(string functionName, string parameterName)
			: base(string.Format("Can't bind parameter '{0}' to function '{1}'", parameterName, functionName))
		{
			_parameterName = parameterName;
		}

		/// <summary>Constructor taking the function name, parameter name and a message.</summary>
		/// <param name="message"/>
		/// <param name="functionName"/>
		/// <param name="parameterName"/>
		public ParameterBindingException(string message, string functionName, string parameterName)
			: base(message, functionName)
		{
			_parameterName = parameterName;
		}

		/// <summary>Constructor taking the function name, parameter name, a message and an inner exception.</summary>
		/// <param name="message"></param>
		/// <param name="inner"></param>
		/// <param name="functionName"/>
		/// <param name="parameterName"/>
		public ParameterBindingException(string message, Exception inner, string functionName, string parameterName)
			: base(message, inner, functionName)
		{
			_parameterName = parameterName;
		}

		/// <summary>Constructor needed for serialization when exception propagates from a remoting server to the client.</summary>
		/// <param name="info"></param>
		/// <param name="context"></param>
		protected ParameterBindingException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
			_parameterName = info.GetString(PARAMETER_NAME);
		}

		/// <summary>Serializes custom content.</summary>
		/// <param name="info"></param>
		/// <param name="context"></param>
		public override void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			base.GetObjectData(info, context);

			info.AddValue(PARAMETER_NAME, _parameterName);
		}

		/// <summary>Returns the name of the parameter.</summary>
		public string ParameterName
		{
			get { return _parameterName; }
		}
	}
}